package com.itheima.service.impl;

import com.itheima.dao.AccountDao;
import com.itheima.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.sql.DataSource;

//@Service
public class AccountServiceImpl_bak implements AccountService {
    @Autowired
    private AccountDao dao;
    /**
     * 注入数据源
     */
    @Autowired
    private DataSource dataSource;

    /**
     * 编程式事务
     * @param outId
     * @param inId
     * @param money
     */
    @Override
    public void transfer(int outId, int inId, double money) {
        //1.构建事务管理器
        DataSourceTransactionManager dstm = new DataSourceTransactionManager();
        //设置数据源
        dstm.setDataSource(dataSource);
        //2.构建事务定义对象:设置隔离级别 传播行为 超时时间 等
        DefaultTransactionDefinition td = new DefaultTransactionDefinition();
        //设置为可重复读隔离级别，保证与mysql一致 》 读未提交
        /*
            mysql默认隔离级别：可重复读
            oracle默认隔离级别：读已提交
         */
        td.setIsolationLevel(TransactionDefinition.ISOLATION_REPEATABLE_READ);
        //设置事务的超时时间
        /*
            事务超时时间，参数默认是-1，表示永不超时（什么时候结束，则结束）
            单位是：秒
         */
        td.setTimeout(10);
        //设置是否为只读事务
        /*
            设置当前事务是否是只读事务
                true：表示只读事务（事务内的操作，只有查询，没有增删改操作）
                false:当前操作存在写操作；
         */
        td.setReadOnly(false);
        //设置事务的传播特性 TODO
        td.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        //3.获取事务状态对象 开启事务
        TransactionStatus ts = dstm.getTransaction(td);
        try {
            //独立的事务 自动开启 自动提交
            dao.outMoney(outId, money);
            //可能在转账过程中发生意外: 转出执行,转入还未执行
            int i = 1/0;
            //独立的事务 自动开启 自动提交
            dao.inMoney(inId, money);
            //提交事务
            dstm.commit(ts);
        } catch (Exception e) {
            e.printStackTrace();
            //回滚事务
            dstm.rollback(ts);
        }
    }

    @Override
    public void transfer2(int outId, int inId, double money) {

    }
}
